<?php

namespace common\service;

use common\model\EntityModel;
use common\model\TaskRelationTagModel;
use support\SingletonTrait;
use think\Exception;

class TaskRelationTagService
{

    // 单例工具
    use SingletonTrait;


    /**
     * 获取更新待办标签的数据
     * @param $taskId
     * @param $newTaskRelationTagList
     * @param $tenantId
     * @param $userId
     * @return array[]
     */
    public function getUpdateTodoTaskRelateTagData($taskId, $newTaskRelationTagList, $tenantId, $userId)
    {
        $taskRelationTagList = model(TaskRelationTagModel::class)->where([
            'task_id' => $taskId
        ])->field("id,task_id,link_module_code,link_id")->select();

        $taskRelationTagMap = [];
        foreach ($taskRelationTagList as $taskRelationTagItem) {
            $taskRelationTagKey = $taskRelationTagItem["link_module_code"] . "_" . $taskRelationTagItem["link_id"];
            $taskRelationTagMap[$taskRelationTagKey] = $taskRelationTagItem;
        }

        $newTaskRelationTagMap = [];
        foreach ($newTaskRelationTagList as $newTaskRelationTagItem) {
            $newTaskRelationTagKey = $newTaskRelationTagItem["link_module_code"] . "_" . $newTaskRelationTagItem["link_id"];
            $newTaskRelationTagMap[$newTaskRelationTagKey] = $newTaskRelationTagItem;
        }

        // 比较出 需要删除的
        $deleteTaskRelationList = array_diff_key($taskRelationTagMap, $newTaskRelationTagMap);

        // 比较出 需要新增的
        $addTaskRelationList = array_diff_key($newTaskRelationTagMap, $taskRelationTagMap);

        //获取需要删除的标签id
        $deleteTaskRelationIds = [];
        foreach ($deleteTaskRelationList as $deleteTaskRelationItem) {
            $deleteTaskRelationIds[] = $deleteTaskRelationItem['id'];
        }

        //创建需要新增的标签数据
        $addTaskRelationData = [];
        foreach ($addTaskRelationList as $addTaskRelationItem) {
            $addTaskRelationData[] = [
                'link_module_code' => $addTaskRelationItem['link_module_code'],
                'link_id' => $addTaskRelationItem['link_id'],
                'task_id' => $taskId,
                'tenant_id' => $tenantId,
                'created_by' => $userId,
                'created' => time(),
                'updated' => time(),
            ];
        }

        return [
            'add_tag' => $addTaskRelationData,
            'delete_tag' => $deleteTaskRelationIds
        ];
    }

    /**
     * 获取任务关联的列表详情
     * @param $taskId
     * @param array $showStepCategoryList
     * @return array[]
     * @throws Exception
     */
    public function getTaskRelationListDetail($taskId, $showStepCategoryList = [])
    {
        $taskRelationList = model(TaskRelationTagModel::class)->where(['task_id' => $taskId])->select();

        if (empty($showStepCategoryList)) {
            $showStepCategoryList = TemplateService::getInstance()->findStepCategoryShowList();
        }

        $showStepCategoryList = array_column($showStepCategoryList, null, 'id');

        $showNameChildrenMap = [];
        foreach ($showStepCategoryList as $showStepCategoryItem) {
            if (empty($showNameChildrenMap[$showStepCategoryItem['show_name']])) {
                $showNameChildrenMap[$showStepCategoryItem['show_name']] = [
                    "children_ids" => [$showStepCategoryItem['id']],
                    "module_code" => $showStepCategoryItem['module_code']
                ];
            } else {
                $showNameChildrenMap[$showStepCategoryItem['show_name']]['children_ids'][] = $showStepCategoryItem['id'];
            }
        }

        //查询代办标签
        $result = [];
        $sceneIds = [];
        $entityIds = [];
        $showStepCategoryIds = [];
        $stepCategoryIds = [];
        $label = [];
        $currentShowName = "";
        foreach ($taskRelationList as $taskRelationItem) {
            if ($taskRelationItem['link_module_code'] == 'show_step_category') {
                $showStepCategoryIds[] = $taskRelationItem['link_id'];
            }

            if ($taskRelationItem['link_module_code'] == 'step_category') {
                $stepCategoryIds[$taskRelationItem['link_id']] = $taskRelationItem['link_id'];
            }

            if ($taskRelationItem['link_module_code'] == 'scene') {
                $sceneIds[] = $taskRelationItem['link_id'];
            }

            $currentModule = module_by_code($taskRelationItem['link_module_code'], false);

            // 判断是否是实体
            if (!empty($currentModule) && $currentModule['type'] == "entity") {
                $entityIds[] = $taskRelationItem['link_id'];
            }

            //名字判定
            $showName = null;

            if (isset($showStepCategoryList[$taskRelationItem['link_id']])) {
                $currentShowName = $showStepCategoryList[$taskRelationItem['link_id']]['show_name'];
                if ($taskRelationItem['link_module_code'] == 'show_step_category') {
                    $showName = $showStepCategoryList[$taskRelationItem['link_id']]['show_name'];
                } elseif ($taskRelationItem['link_module_code'] == 'step_category') {
                    $showName = $showStepCategoryList[$taskRelationItem['link_id']]['name'];
                }
            }


            //名字映射
            if (!empty($showName) && !in_array($showName, $label)) {
                $label[] = $showName;
            }
        }


        //合并工序 大分类和小分类只会同时存在一个
        $showStepCategoryMap = [];
        if (!empty($showStepCategoryIds)) {
            foreach ($showStepCategoryIds as $showStepCategoryId) {
                if (!isset($showStepCategoryList[$showStepCategoryId])) {
                    continue;
                }

                $currentStepCategory = $showStepCategoryList[$showStepCategoryId];
                $currentStepCategory['link_module_code'] = 'step_category';

                if (!isset($showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']])) {
                    $showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']] = [
                        'id' => $showStepCategoryList[$showStepCategoryId]['show_name'],
                        'name' => $showStepCategoryList[$showStepCategoryId]['show_name'],
                        'link_module_code' => 'show_step_category',
                        'children' => [$currentStepCategory]
                    ];
                } else {
                    $showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']]['children'][] = $currentStepCategory;
                }
            }

            $result[] = [
                'code' => 'show_step_category',
                'count' => count($showStepCategoryMap),
                'list' => array_values($showStepCategoryMap)
            ];

        } elseif (!empty($stepCategoryIds)) {
            $stepCategoryData = array_values(array_intersect_key($showStepCategoryList, $stepCategoryIds));

            $stepCategoryData = array_map(function ($stepCategoryItem) {
                $stepCategoryItem['link_module_code'] = 'step_category';
                return $stepCategoryItem;
            }, $stepCategoryData);


            $result[] = [
                'code' => 'step_category',
                'count' => count($stepCategoryData),
                'list' => $stepCategoryData
            ];
        }

        //是否存在场次
        if (!empty($sceneIds)) {
            $requestData = [
                'param' => [
                    'filter' => [
                        'id' => ['-in', $sceneIds]
                    ],
                ],
            ];
            $sceneList = teamones_request('teamones-script', 'scene/select', $requestData);
            $sceneList = $sceneList['data'] ?? [];

            $sceneEpisodeIds = array_column($sceneList, 'episode_id');

            $sceneEpisodeList = model(EntityModel::class)->where(['id' => ["IN", $sceneEpisodeIds]])->field("id,name")->select();
            $sceneEpisodeList = array_column($sceneEpisodeList, null, 'id');

            $sceneList = array_map(function ($sceneItem) use ($sceneEpisodeList) {
                $sceneItem['episode_code'] = $sceneEpisodeList[$sceneItem['id']] ?? "";
                return $sceneItem;
            }, $sceneList);

            $result[] = [
                'code' => 'scene',
                'count' => count($sceneList),
                'list' => $sceneList
            ];
        }


        //是否存在实体
        $entityMap = [];
        $episodeResult = [];
        if (!empty($entityIds)) {
            $entityList = model(EntityModel::class)->where(['id' => ["IN", $entityIds]])->select();
            foreach ($entityList as $entityItem) {
                $currentEntityModuleCode = module_by_id($entityItem['module_id'])['code'];
                $entityItem = array_merge($entityItem, get_no_prefix_json_fields($entityItem['json'], $currentEntityModuleCode));
                // 统一查询id
                if ($currentEntityModuleCode == 'design') {
                    $entityItem['design'] = $entityItem['id'];
                }

                $entityMap[$currentEntityModuleCode][] = $entityItem;

                if ($currentEntityModuleCode == 'episode') {
                    $episodeResult[] = $entityItem;
                }
            }
            foreach ($entityMap as $entityModuleCode => $entityItem) {
                $result[] = [
                    'code' => $entityModuleCode,
                    'count' => count($entityItem),
                    'list' => $entityItem
                ];
            }
        }

        $tmp = [
            'result' => $result,
            'label' => $label,
            'episode' => $episodeResult,
            'children_ids' => $showNameChildrenMap[$currentShowName]['children_ids'] ?? [],
        ];

        if (isset($showNameChildrenMap[$currentShowName]['module_code'])) {
            $currentModuleCode = $showNameChildrenMap[$currentShowName]['module_code'];
            if (in_array($currentModuleCode, ['asset', 'level', 'design', 'shot', 'storyboard'])) {
                $tmp['count_module_code'] = $currentModuleCode;
            }
        }
        return $tmp;
    }

    /**
     * 获取任务关联的列表详情
     * @param $taskIdList
     * @param array $showStepCategoryList
     * @return array[]
     * @throws Exception
     */
    public function getTaskRelationListDetailList($taskIdList, $showStepCategoryList = [])
    {
        $taskRelationList = model(TaskRelationTagModel::class)->where(['task_id' => ['IN', implode(',', $taskIdList)]])->select();

        if (empty($showStepCategoryList)) {
            $showStepCategoryList = TemplateService::getInstance()->findStepCategoryShowList();
        }

        $showStepCategoryList = array_column($showStepCategoryList, null, 'id');

        $showNameChildrenMap = [];
        foreach ($showStepCategoryList as $showStepCategoryItem) {
            if (empty($showNameChildrenMap[$showStepCategoryItem['show_name']])) {
                $showNameChildrenMap[$showStepCategoryItem['show_name']] = [
                    "children_ids" => [$showStepCategoryItem['id']],
                    "module_code" => $showStepCategoryItem['module_code']
                ];
            } else {
                $showNameChildrenMap[$showStepCategoryItem['show_name']]['children_ids'][] = $showStepCategoryItem['id'];
            }
        }

        //查询代办标签
        $taskRelationListGrouped = array_group_by($taskRelationList, 'task_id');


        $sceneIds = [];
        $taskSceneIdList = [];
        $entityIds = [];
        $taskEntityIds = [];
        $res = [];
        foreach ($taskRelationListGrouped as $taskId => $taskRelationList) {

            $result = [];
            $showStepCategoryIds = [];
            $stepCategoryIds = [];
            $label = [];
            $currentShowName = "";
            foreach ($taskRelationList as $taskRelationItem) {
                if ($taskRelationItem['link_module_code'] == 'show_step_category') {
                    $showStepCategoryIds[] = $taskRelationItem['link_id'];
                }
                if ($taskRelationItem['link_module_code'] == 'step_category') {
                    $stepCategoryIds[$taskRelationItem['link_id']] = $taskRelationItem['link_id'];
                }
                if ($taskRelationItem['link_module_code'] == 'scene') {
                    $sceneIds[] = $taskRelationItem['link_id'];
                    $taskSceneIdList[$taskId][] = $taskRelationItem['link_id'];
                }
                $currentModule = module_by_code($taskRelationItem['link_module_code'], false);
                // 判断是否是实体
                if (!empty($currentModule) && $currentModule['type'] == "entity") {
                    $entityIds[] = $taskRelationItem['link_id'];
                    $taskEntityIds[$taskId][] = $taskRelationItem['link_id'];
                }
                //名字判定
                $showName = null;
                if (isset($showStepCategoryList[$taskRelationItem['link_id']])) {
                    $currentShowName = $showStepCategoryList[$taskRelationItem['link_id']]['show_name'];
                    if ($taskRelationItem['link_module_code'] == 'show_step_category') {
                        $showName = $showStepCategoryList[$taskRelationItem['link_id']]['show_name'];
                    } elseif ($taskRelationItem['link_module_code'] == 'step_category') {
                        $showName = $showStepCategoryList[$taskRelationItem['link_id']]['name'];
                    }
                }
                //名字映射
                if (!empty($showName) && !in_array($showName, $label)) {
                    $label[] = $showName;
                }
            }
            //合并工序 大分类和小分类只会同时存在一个
            $showStepCategoryMap = [];
            if (!empty($showStepCategoryIds)) {
                foreach ($showStepCategoryIds as $showStepCategoryId) {
                    if (!isset($showStepCategoryList[$showStepCategoryId])) {
                        continue;
                    }
                    $currentStepCategory = $showStepCategoryList[$showStepCategoryId];
                    $currentStepCategory['link_module_code'] = 'step_category';
                    if (!isset($showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']])) {
                        $showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']] = [
                            'id' => $showStepCategoryList[$showStepCategoryId]['show_name'],
                            'name' => $showStepCategoryList[$showStepCategoryId]['show_name'],
                            'link_module_code' => 'show_step_category',
                            'children' => [$currentStepCategory]
                        ];
                    } else {
                        $showStepCategoryMap[$showStepCategoryList[$showStepCategoryId]['show_name']]['children'][] = $currentStepCategory;
                    }
                }
                $result[] = [
                    'code' => 'show_step_category',
                    'count' => count($showStepCategoryMap),
                    'list' => array_values($showStepCategoryMap)
                ];
            } elseif (!empty($stepCategoryIds)) {
                $stepCategoryData = array_values(array_intersect_key($showStepCategoryList, $stepCategoryIds));
                $stepCategoryData = array_map(function ($stepCategoryItem) {
                    $stepCategoryItem['link_module_code'] = 'step_category';
                    return $stepCategoryItem;
                }, $stepCategoryData);
                $result[] = [
                    'code' => 'step_category',
                    'count' => count($stepCategoryData),
                    'list' => $stepCategoryData
                ];
            }


            $res[$taskId] = [
                'result' => $result,
                'label' => $label,
                'episode' => [],
                'children_ids' => $showNameChildrenMap[$currentShowName]['children_ids'] ?? [],
            ];
            if (isset($showNameChildrenMap[$currentShowName]['module_code'])) {
                $currentModuleCode = $showNameChildrenMap[$currentShowName]['module_code'];
                if (in_array($currentModuleCode, ['asset', 'level', 'design', 'shot', 'storyboard'])) {
                    $res[$taskId]['count_module_code'] = $currentModuleCode;
                }
            }
        }

        //是否存在实体
        if (!empty($entityIds)) {
            $entityList = model(EntityModel::class)->where(['id' => ["IN", $entityIds]])->select();
            $entityList = array_column($entityList, null, 'id');

            foreach ($taskEntityIds as $taskId => $entityIdList) {

                $entityMap = [];
                $episodeResult = [];
                foreach ($entityIdList as $entityId) {
                    if (!isset($entityList[$entityId])) {
                        continue;
                    }
                    $entityItem = $entityList[$entityId];

                    $currentEntityModuleCode = module_by_id($entityItem['module_id'])['code'];
                    $entityItem = array_merge($entityItem, get_no_prefix_json_fields($entityItem['json'], $currentEntityModuleCode));
                    // 统一查询id
                    if ($currentEntityModuleCode == 'design') {
                        $entityItem['design'] = $entityItem['id'];
                    }

                    $entityMap[$currentEntityModuleCode][] = $entityItem;

                    if ($currentEntityModuleCode == 'episode') {
                        $episodeResult[] = $entityItem;
                    }
                }
                foreach ($entityMap as $entityModuleCode => $entityItem) {
                    $res[$taskId]['result'][] = [
                        'code' => $entityModuleCode,
                        'count' => count($entityItem),
                        'list' => $entityItem
                    ];
                }
                $res[$taskId]['episode'] = $episodeResult;
            }
        }

        //是否存在场次
        if (!empty($sceneIds)) {
            $requestData = ['param' => ['filter' => [
                'id' => ['-in', $sceneIds]
            ],],];
            $sceneList = teamones_request('teamones-script', 'scene/select', $requestData);
            $sceneList = $sceneList['data'] ?? [];
            $sceneEpisodeIds = array_column($sceneList, 'episode_id');
            $sceneEpisodeList = model(EntityModel::class)->where(['id' => ["IN", $sceneEpisodeIds]])->field("id,name")->select();
            $sceneEpisodeList = array_column($sceneEpisodeList, null, 'id');
            $sceneList = array_map(function ($sceneItem) use ($sceneEpisodeList) {
                $sceneItem['episode_code'] = $sceneEpisodeList[$sceneItem['id']] ?? "";
                return $sceneItem;
            }, $sceneList);
            $sceneList = array_column($sceneList, null, 'id');
            foreach ($taskSceneIdList as $taskId => $sceneIdList) {
                $currentSceneList = [];
                foreach ($sceneIdList as $sceneId) {
                    if (isset($sceneList[$sceneId])) {
                        $currentSceneList[] = $sceneList[$sceneId];
                    }
                }
                if (!empty($currentSceneList)) {
                    $res[$taskId]['result'][] = [
                        'code' => 'scene',
                        'count' => count($currentSceneList),
                        'list' => $currentSceneList
                    ];
                }
            }
        }

        return $res;
    }
}
